import { PlusOutlined, ReloadOutlined, SettingOutlined, KeyOutlined } from '@ant-design/icons';

import { systemRoleAllListApi, type SysRoleItem } from '@/api/systemRoleApi';
import {
  systemUserListApi,
  systemUserDeleteApi,
  systemUserSaveOrUpdateApi,
  systemUserEnableApi,
  systemUserResetPasswordApi,
  type SysUserItem,
} from '@/api/systemUserApi';
import type { OperationType } from '@/constants';
import { OperationTypeList, EnableStatusType, EnableActionText } from '@/constants';
import { TableLocalePresets } from '@/utils/tableUtils';

import SystemUserAddForm from './modules/add';

import type { ActionType, ProColumns } from '@ant-design/pro-components';

/**
 * 系统用户管理页面
 * 提供用户的增删改查功能，包括用户列表展示、新增用户、编辑用户、删除用户等操作
 */

/**
 * 扩展的用户项接口
 * 在基础 SysUserItem 基础上添加表单和UI需要的字段
 */
interface ExtendedUserItem extends SysUserItem {
  /** 确认密码字段 */
  confirmPassword?: string;
}

/**
 * 用户列表API响应类型
 */
interface UserListResponse {
  /** 用户记录列表 */
  records: SysUserItem[];
  /** 总记录数 */
  total: number;
  /** 当前页码 */
  current: number;
  /** 每页大小 */
  size: number;
}

/**
 * 系统用户管理主组件
 */
const SystemUser = () => {
  // 表格操作引用
  const actionRef = useRef<ActionType>(null);
  // 表单实例
  const [form] = AForm.useForm();

  // 抽屉显示状态
  const [drawerShow, setDrawerShow] = useState(false);
  // 抽屉操作类型（新增/编辑/详情）
  const [drawerType, setDrawerType] = useState<OperationType>('ADD');
  // 当前操作的记录数据
  const [currentRecord, setCurrentRecord] = useState<ExtendedUserItem>({} as ExtendedUserItem);

  // 角色选项列表
  const [roleOptions, setRoleOptions] = useState<Array<{ label: string; value: number }>>([]);

  /**
   * 获取所有角色列表
   */
  const fetchRoleOptions = async () => {
    try {
      const res = await systemRoleAllListApi();
      if (res.success && res.data) {
        const options = res.data.map((role: SysRoleItem) => ({
          label: role.name || '',
          value: role.id || 0,
        }));
        setRoleOptions(options);
      }
    } catch (error) {
      console.error('获取角色列表失败:', error);
    }
  };

  // 组件初始化时获取角色列表
  useEffect(() => {
    fetchRoleOptions();
  }, []);

  /**
   * ProTable 数据请求函数
   * @param params 查询参数，包含分页、筛选等信息
   * @returns 返回符合 ProTable 要求的数据格式
   */
  const fetchData = async (params: Record<string, unknown>) => {
    try {
      // 过滤掉无效参数（undefined、null、空字符串）
      const validParams = Object.entries(params).reduce(
        (acc, [key, value]) => {
          if (value !== undefined && value !== null && value !== '') {
            acc[key] = value;
          }
          return acc;
        },
        {} as Record<string, unknown>
      );

      const res = await systemUserListApi({
        ...validParams,
        page: validParams.current,
      });

      // 检查API响应是否成功
      if (!res || !res.success) {
        window.$message.error(res?.message || '获取用户列表失败');
        return {
          success: false,
          data: [],
          total: 0,
        };
      }

      // 类型断言并提取数据
      const responseData = res.data as unknown as UserListResponse;
      return {
        success: true,
        data: Array.isArray(responseData?.records) ? responseData.records : [],
        total: responseData?.total ?? 0,
      };
    } catch (error) {
      console.error('获取用户列表失败:', error);
      window.$message.error('获取用户列表失败，请稍后重试');
      return {
        success: false,
        data: [],
        total: 0,
      };
    }
  };

  /**
   * 删除用户处理函数
   * @param record 要删除的用户记录
   */
  const handleDelete = async (record: SysUserItem) => {
    // 参数验证
    if (!record || !record.id) {
      window.$message.error('删除失败：用户ID不存在');
      return;
    }

    try {
      const res = await systemUserDeleteApi({ id: record.id });
      if (res.success) {
        window.$message.success('删除成功');
        // 刷新表格数据
        actionRef.current?.reload();
      } else {
        window.$message.error(res.message || '删除失败');
      }
    } catch (error) {
      console.error('删除用户失败:', error);
      window.$message.error('删除失败，请稍后重试');
    }
  };

  /**
   * 切换用户启用状态
   * @param record 用户记录
   * @param checked 新的启用状态
   */
  const handleToggleEnable = async (record: SysUserItem, checked: boolean) => {
    // 参数验证
    if (!record || !record.id) {
      window.$message.error('切换状态失败：用户ID不存在');
      return;
    }

    try {
      const res = await systemUserEnableApi({
        userId: record.id,
        isEnable: checked ? EnableStatusType.ENABLED.value : EnableStatusType.DISABLED.value,
      });
      if (res.success) {
        const actionText = checked
          ? EnableActionText.ENABLE_SUCCESS
          : EnableActionText.DISABLE_SUCCESS;
        window.$message.success(actionText);
        // 刷新表格数据
        actionRef.current?.reload();
      } else {
        window.$message.error(res.message || '操作失败');
      }
    } catch (error) {
      console.error('切换用户状态失败:', error);
      window.$message.error('操作失败，请稍后重试');
    }
  };

  /**
   * 重置用户密码
   * @param record 用户记录
   */
  const handleResetPassword = async (record: SysUserItem) => {
    // 参数验证
    if (!record || !record.id) {
      window.$message.error('重置密码失败：用户ID不存在');
      return;
    }

    try {
      const res = await systemUserResetPasswordApi({ userId: record.id });
      if (res.success) {
        window.$message.success('密码重置成功');
      } else {
        window.$message.error(res.message || '密码重置失败');
      }
    } catch (error) {
      console.error('重置密码失败:', error);
      window.$message.error('密码重置失败，请稍后重试');
    }
  };

  /**
   * ProTable 表格列配置
   * 定义表格的列结构、搜索条件、渲染方式等
   */
  const columns: ProColumns<SysUserItem>[] = [
    {
      title: '用户名',
      dataIndex: 'userName',
      key: 'userName',
      copyable: false,
    },
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '手机号',
      dataIndex: 'phone',
      key: 'phone',
    },
    {
      title: '角色',
      dataIndex: 'roleName',
      key: 'roleName',
      search: false,
      render: (_, record) => <ATag color="blue">{record.roleName || '-'}</ATag>,
    },
    {
      title: '状态',
      dataIndex: 'isEnable',
      key: 'isEnable',
      valueEnum: {
        [EnableStatusType.ENABLED.value]: {
          text: EnableStatusType.ENABLED.label,
          status: 'Success',
        },
        [EnableStatusType.DISABLED.value]: {
          text: EnableStatusType.DISABLED.label,
          status: 'Error',
        },
      },
      render: (_, record) => (
        <ASwitch
          checked={record.isEnable === EnableStatusType.ENABLED.value}
          onChange={checked => handleToggleEnable(record, checked)}
          checkedChildren={EnableStatusType.ENABLED.label}
          unCheckedChildren={EnableStatusType.DISABLED.label}
        />
      ),
    },
    {
      title: '操作',
      key: 'action',
      width: 250,
      fixed: 'right',
      search: false,
      render: (_, record) => (
        <ASpace size="small">
          <AButton
            type="link"
            size="small"
            onClick={() => {
              if (record.id) {
                const formData: ExtendedUserItem = {
                  ...record,
                };

                setCurrentRecord(formData);
                setDrawerType('EDIT');
                setDrawerShow(true);
                form.setFieldsValue(formData);
              }
            }}
          >
            编辑
          </AButton>
          <AButton
            type="link"
            size="small"
            icon={<KeyOutlined />}
            onClick={() => handleResetPassword(record)}
          >
            重置密码
          </AButton>
          <APopconfirm
            title="您确定要删除吗？"
            description={`请确认删除用户【${record.name || record.userName || ''}】`}
            onConfirm={() => {
              handleDelete(record);
            }}
            okType="danger"
            okText="确认"
            cancelText="取消"
          >
            <AButton type="link" size="small" danger>
              删除
            </AButton>
          </APopconfirm>
        </ASpace>
      ),
    },
  ];

  /**
   * 关闭抽屉并重置状态
   */
  const handleDrawerClose = () => {
    setCurrentRecord({} as ExtendedUserItem);
    setDrawerType('ADD');
    setDrawerShow(false);
  };

  /**
   * 表单提交处理函数
   * 处理新增和编辑用户的表单提交
   */
  const handleSubmit = async () => {
    try {
      // 表单验证
      const params = await form.validateFields();
      const newParams = {
        ...currentRecord,
        ...params,
      };

      // 调用保存或更新API
      const res = await systemUserSaveOrUpdateApi(newParams);
      if (res.success) {
        window.$message.success(drawerType === 'ADD' ? '添加成功' : '更新成功');
        handleDrawerClose();
        actionRef.current?.reload(); // 刷新表格数据
      } else {
        window.$message.error(res.message || '操作失败');
      }
    } catch (error) {
      console.error('表单提交失败:', error);
      window.$message.error('表单验证失败，请检查输入');
    }
  };

  return (
    <div className="page-wrapper">
      <ADrawer
        destroyOnHidden
        title={`用户${OperationTypeList[drawerType].label}`}
        width={600}
        closable={{ 'aria-label': 'Close Button' }}
        footer={
          <ARow justify="end">
            <ASpace>
              <AButton
                onClick={() => {
                  setDrawerShow(false);
                }}
              >
                返回
              </AButton>
              {drawerType !== 'DETAIL' && (
                <AButton type="primary" onClick={handleSubmit}>
                  提交
                </AButton>
              )}
            </ASpace>
          </ARow>
        }
        onClose={handleDrawerClose}
        open={drawerShow}
      >
        <div className="w-full px-8 py-8">
          <AForm form={form} layout="vertical" labelAlign="right" labelCol={{ span: 12 }}>
            <SystemUserAddForm
              form={form}
              data={currentRecord as SysUserItem}
              roleOptions={roleOptions}
              isEdit={drawerType === 'EDIT'}
            />
          </AForm>
        </div>
      </ADrawer>
      <div className="page-title">
        <div className="page-main-title">用户管理</div>
        <div className="page-sub-title">管理系统用户，配置用户角色和状态</div>
      </div>
      <div className="page-content-box">
        <div className="page-content flex show-bg">
          <div className="w-full">
            <PProTable<SysUserItem>
              className="mh-table"
              actionRef={actionRef}
              columns={columns}
              request={fetchData}
              rowKey="id"
              search={{
                span: 6,
                labelWidth: 'auto',
                defaultCollapsed: false,
              }}
              pagination={{
                defaultPageSize: 10,
                showSizeChanger: true,
                showQuickJumper: true,
                showTotal: (total, range) =>
                  `共 ${total} 项数据，当前显示第 ${range[0]}-${range[1]} 项`,
              }}
              scroll={{ x: 1000 }}
              size="small"
              options={{
                density: false,
                reloadIcon: (
                  <AButton icon={<ReloadOutlined />} key="reload">
                    刷新
                  </AButton>
                ),
                setting: {
                  draggable: true,
                  checkable: true,
                  showListItemOption: true,
                  settingIcon: <AButton icon={<SettingOutlined />}>设置</AButton>,
                  listsHeight: 400,
                },
              }}
              toolBarRender={() => [
                <AButton
                  key="add"
                  icon={<PlusOutlined />}
                  type="primary"
                  onClick={() => {
                    form.resetFields();
                    setCurrentRecord({});
                    setDrawerType('ADD');
                    setDrawerShow(true);
                    form.setFieldsValue({
                      isEnable: EnableStatusType.ENABLED.value, // 默认状态为启用
                    });
                  }}
                >
                  新增
                </AButton>,
              ]}
              locale={TableLocalePresets.product(actionRef)}
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default SystemUser;
